home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / DockStrip / MorePatches / MoreCFMPatches / MoreCFMPatchesTest / MoreCFMPatchesTest.c next >
C/C++ Source or Header  |  2000-06-23  |  8KB  |  288 lines

  1. /*
  2.     File:        MoreCFMPatches.c
  3.  
  4.     Contains:    Test CFM patching technology.
  5.  
  6.     Written by:    Quinn
  7.  
  8.     Copyright:    Copyright © 1998-1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.  
  20.          <1>     16/3/99    Quinn   First checked in.
  21. */
  22.  
  23. /////////////////////////////////////////////////////////////////
  24.  
  25. // MoreIsBetter Setup
  26.  
  27. #include "MoreSetup.h"
  28.  
  29. // Mac OS Interfaces
  30.  
  31. #include <CodeFragments.h>
  32. #include <LowMem.h>
  33.  
  34. // ANSI C Interfaces
  35.  
  36. #include <stdio.h>
  37. #include <string.h>
  38.  
  39. // Project Interfaces
  40.  
  41. #include "MoreCFMPatches.h"
  42.  
  43. /////////////////////////////////////////////////////////////////
  44. #pragma mark ---- Basic Functionality -----
  45.  
  46. // In this test, we patch LMGetScrDmpEnb twice, call through
  47. // to the existing routine in both patches, while printing out
  48. // entry and exit markers.  Seems to work (-:
  49.  
  50. typedef pascal UInt8 (*LMGetScrDmpEnbProc)(void);
  51.  
  52. static pascal UInt8 MyLMGetScrDmpEnb(void)
  53. {
  54.     UInt8 result;
  55.     
  56.     printf("    Enter MyLMGetScrDmpEnb\n");
  57.     result = ( (LMGetScrDmpEnbProc) gMoreCFMPatchesCallThrough)();
  58.     printf("    Leave MyLMGetScrDmpEnb\n");
  59.     return result;
  60. }
  61.  
  62. static pascal UInt8 MyLMGetScrDmpEnb2(void)
  63. {
  64.     UInt8 result;
  65.  
  66.     printf("  Enter MyLMGetScrDmpEnb2\n");
  67.     result = ( (LMGetScrDmpEnbProc) gMoreCFMPatchesCallThrough)();
  68.     printf("  Leave MyLMGetScrDmpEnb2\n");
  69.     return result;
  70. }
  71.  
  72. static void BasicFunctionality(void)
  73. {
  74.     OSStatus err;
  75.     OSStatus junk;
  76.     CFragConnectionID connID;
  77.     Ptr junkMain;
  78.     Str255 junkMessage;
  79.     CFragSymbolClass junkSymClass;
  80.     Ptr symAddr;
  81.     UInt8 junkUInt8;
  82.     void *origCodePointer;
  83.     
  84.     printf("Basic functionality testing...\n");    
  85.     err = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch, kFindCFrag, &connID, &junkMain, junkMessage);
  86.     if (err == noErr) {
  87.         err = FindSymbol(connID, "\pLMGetScrDmpEnb", &symAddr, &junkSymClass);
  88.     }
  89.     if (err == noErr) {
  90.         origCodePointer = ((TVector *)symAddr)->codePointer;
  91.         err = MorePatchTVector((TVector *) symAddr, (TVector *) MyLMGetScrDmpEnb,  'KWN1', nil);
  92.         if (err == noErr) {
  93.             MoreAssertQ(origCodePointer != ((TVector *)symAddr)->codePointer);
  94.             err = MorePatchTVector((TVector *) symAddr, (TVector *) MyLMGetScrDmpEnb2, 'KWN2', nil);
  95.             if (err == noErr) {
  96.                 junkUInt8 = LMGetScrDmpEnb();
  97.                 junk = MoreUnpatchTVector((TVector *) symAddr, (TVector *) MyLMGetScrDmpEnb2);
  98.                 MoreAssertQ(junk == noErr);
  99.             }
  100.             junk = MoreUnpatchTVector((TVector *) symAddr, (TVector *) MyLMGetScrDmpEnb);
  101.             MoreAssertQ(junk == noErr);
  102.         }
  103.         MoreAssertQ(origCodePointer == ((TVector *)symAddr)->codePointer);
  104.     }
  105.     if (err == noErr) {
  106.         printf("Success!\n");
  107.     } else {
  108.         printf("Failed with error %ld.\n", err);
  109.     }
  110. }
  111.  
  112. /////////////////////////////////////////////////////////////////
  113. #pragma mark ---- Ordering Tests -----
  114.  
  115. typedef void (*OrderProc)(char *str);
  116.  
  117. static void OBase(char *str)
  118. {
  119.     strcpy(str, "OBase");
  120. }
  121.  
  122. static void O1(char *str)
  123. {
  124.     ((OrderProc) gMoreCFMPatchesCallThrough)(str);
  125.     strcat(str, "->O1");
  126. }
  127.  
  128. static void O2(char *str)
  129. {
  130.     ((OrderProc) gMoreCFMPatchesCallThrough)(str);
  131.     strcat(str, "->O2");
  132. }
  133.  
  134. static void O3(char *str)
  135. {
  136.     ((OrderProc) gMoreCFMPatchesCallThrough)(str);
  137.     strcat(str, "->O3");
  138. }
  139.  
  140. static void OrderingTests(void)
  141.     // Tests that patches are applied in the order we expected
  142.     // and that they are executed in the order they're applied.
  143. {
  144.     OSStatus junk;
  145.     char str[256];
  146.     OrderProc obaseProc;
  147.  
  148.     printf("Ordering tests...\n");
  149.     
  150.     // We call OBase through a routine pointer to force it to go through
  151.     // the TVector.  Otherwise, because the routine is implemented in the
  152.     // same file as the caller, the compiler optimises the TVector goop away.
  153.         
  154.     obaseProc = OBase;
  155.     
  156.     obaseProc(str);
  157.     MoreAssertQ(strcmp(str, "OBase") == 0);
  158.     
  159.     junk = MorePatchTVector((TVector *) OBase, (TVector *) O1,  'Oone', nil);
  160.     MoreAssertQ(junk == noErr);
  161.     
  162.     obaseProc(str);
  163.     MoreAssertQ(strcmp(str, "OBase->O1") == 0);
  164.     
  165.     junk = MorePatchTVector((TVector *) OBase, (TVector *) O2, 'Otwo', nil);
  166.     MoreAssertQ(junk == noErr);
  167.  
  168.     obaseProc(str);
  169.     MoreAssertQ(strcmp(str, "OBase->O1->O2") == 0);
  170.  
  171.     junk = MorePatchTVector((TVector *) OBase, (TVector *) O3, 'Otri', nil);
  172.     MoreAssertQ(junk == noErr);
  173.  
  174.     obaseProc(str);
  175.     MoreAssertQ(strcmp(str, "OBase->O1->O2->O3") == 0);
  176.  
  177.     // Here we try a difficult case, namely pulling a patch out
  178.     // of the middle of the patch chain.
  179.         
  180.     junk = MoreUnpatchTVector((TVector *) OBase, (TVector *) O2);
  181.     MoreAssertQ(junk == noErr);
  182.  
  183.     obaseProc(str);
  184.     MoreAssertQ(strcmp(str, "OBase->O1->O3") == 0);
  185.  
  186.     junk = MoreUnpatchTVector((TVector *) OBase, (TVector *) O1);
  187.     MoreAssertQ(junk == noErr);
  188.  
  189.     obaseProc(str);
  190.     MoreAssertQ(strcmp(str, "OBase->O3") == 0);
  191.     
  192.     junk = MoreUnpatchTVector((TVector *) OBase, (TVector *) O3);
  193.     MoreAssertQ(junk == noErr);
  194.  
  195.     obaseProc(str);
  196.     MoreAssertQ(strcmp(str, "OBase") == 0);
  197.     
  198.     printf("Success!\n");
  199. }
  200.  
  201. #pragma mark ---- Information Tests -----
  202.  
  203. static OSStatus PrintPatchChain(TVector *patchedTVector)
  204. {
  205.     OSStatus err;
  206.     ItemCount patchCount;
  207.     ItemCount patchIndex;
  208.     OSType  creator;
  209.     TVector *tVector;
  210.     void    *refcon;
  211.     
  212.     err = MoreCountPatches(patchedTVector, &patchCount);
  213.     if (err == noErr) {
  214.         for (patchIndex = 1; patchIndex <= patchCount; patchIndex++) {
  215.             err = MoreGetIndexedPatchInfo(patchedTVector, patchIndex, kPatchInfoCreator, &creator, sizeof(creator));
  216.             if (err == noErr) {
  217.                 err = MoreGetIndexedPatchInfo(patchedTVector, patchIndex, kPatchInfoTVector, &tVector, sizeof(tVector));
  218.             }
  219.             if (err == noErr) {
  220.                 err = MoreGetIndexedPatchInfo(patchedTVector, patchIndex, kPatchInfoRefcon, &refcon, sizeof(refcon));
  221.             }
  222.             if (err == noErr) {
  223.                 printf("%ld $%08lx '%4.4s' $%ld -> ", patchIndex, tVector, &creator, refcon);
  224.             } else {
  225.                 break;
  226.             }
  227.         }
  228.         printf("\n");
  229.     }
  230.     
  231.     return err;
  232. }
  233.  
  234. static void InformationTests(void)
  235.     // Tests that the patch information routines are
  236.     // working as expected.
  237. {
  238.     OSStatus junk;
  239.  
  240.     printf("Information tests...\n");
  241.     
  242.     junk = MorePatchTVector((TVector *) OBase, (TVector *) O1, 'Oone', (void *) 1);
  243.     MoreAssertQ(junk == noErr);
  244.     junk = PrintPatchChain((TVector *)  OBase);
  245.     MoreAssertQ(junk == noErr);
  246.     junk = MorePatchTVector((TVector *) OBase, (TVector *) O2, 'Otwo', (void *) 2);
  247.     MoreAssertQ(junk == noErr);
  248.     junk = PrintPatchChain((TVector *)  OBase);
  249.     MoreAssertQ(junk == noErr);
  250.     junk = MorePatchTVector((TVector *) OBase, (TVector *) O3, 'Otri', (void *) 3);
  251.     MoreAssertQ(junk == noErr);
  252.     junk = PrintPatchChain((TVector *)  OBase);
  253.     MoreAssertQ(junk == noErr);
  254.  
  255.     junk = MoreUnpatchTVector((TVector *) OBase, (TVector *) O2);
  256.     MoreAssertQ(junk == noErr);
  257.     junk = PrintPatchChain((TVector *) OBase);
  258.     MoreAssertQ(junk == noErr);
  259.     junk = MoreUnpatchTVector((TVector *) OBase, (TVector *) O1);
  260.     MoreAssertQ(junk == noErr);
  261.     junk = PrintPatchChain((TVector *) OBase);
  262.     MoreAssertQ(junk == noErr);
  263.     junk = MoreUnpatchTVector((TVector *) OBase, (TVector *) O3);
  264.     MoreAssertQ(junk == noErr);
  265.     junk = PrintPatchChain((TVector *) OBase);
  266.     MoreAssertQ(junk == kVectorNotPatchedByUsErr);
  267.     
  268.     printf("Success!\n");
  269. }
  270.  
  271. /////////////////////////////////////////////////////////////////
  272. #pragma mark ---- Main Line -----
  273.  
  274. void main(void)
  275. {
  276.     printf("Hello Cruel World!\n");
  277.     printf("MoreCFMPatchesTest\n");
  278.     printf("-- A simple test program for the MoreCFMPatches library.\n");
  279.  
  280.     BasicFunctionality();
  281.     printf("\n");
  282.     OrderingTests();
  283.     printf("\n");
  284.     InformationTests();
  285.     printf("\n");
  286.     
  287.     printf("Done.  Press command-Q to Quit.\n");
  288. }